// 给定一个由若干 0 和 1 组成的数组 A，我们最多可以将 K 个值从 0 变成 1 。
// 返回仅包含 1 的最长（连续）子数组的长度。

const longestOnes = function (A: number[], K: number): number {
    let left = 0;
    let right = 0;
    let res = 0;
    let zeroCount = 0;// 零计数
    while (right < A.length) {
        // 处理右指针划到 0 的情况
        if (A[right] === 0) {
            zeroCount++;
            // 必定可以保证每轮循环中左指针是合理的
            while (zeroCount > K) {
                if (A[left] === 0) {
                    zeroCount--;
                }
                left++;
            }
        }
        // 防止死循环，右指针每轮循环中都需要右移
        right++;
        res = Math.max(res, right - left);
    }
    return res;
};

longestOnes([0, 0, 1, 1, 1, 0, 0], 0)

// 看到连续最长子数组，下意识想到滑动窗口解法...
// 为了方便边界处理使用左闭右开的方式滑动
// 首先当右边界新加入的元素为 1 时是最简单的，直接右划然后更新区间长度即可
// 比较复杂的是右指针指向 0 的时候，此时先需要让零计数+1
// 之后需要考虑是否要操作右指针的情况
// 当零计数大于K时，走入循环，我们不断地移动左指针右移
// 然后判断左指针指向的元素是否等于 0 ，如果存在等于 0 的情况
// 左指针右移的同时可以让零计数 -1，此时解放右指针，右指针可以右移
// 这里还有需要额外注意的部分，防止被边界情况如：[0, 0, 1, 1, 1, 0, 0], 0 堵死
// 右指针在每轮循环中都需要右移（左指针在每轮循环中必定保证是合理的）
